package game;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Random;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.Sprite;
import obj.Bullet;
import obj.Kappa;
import obj.Urchin;
import obj.Player;
import obj.Weapon;

import c.CWin;

public class Game extends CWin {
	private Image imgbg;
	private Player player;
	private Image imgScore;
	private Image imgBullet;
	private Image[] imgUrchin;
	private Image imgTile;
	private Image imgLife;
	private Image imgHealth;
	Image imgBoss[];
	Image imgKappa[];
	// private Weapon weapon;
	public int level, score;
	public int row;
	public int column;
	private int[][] arrMap;
	public static int distance_x;
	public static int distance_y;
	short delayEnemy;
	Weapon weapon;
	Weapon[] weapons;
	Bullet bullet;
	Bullet[] bullets;
	Urchin[] urchinEnemies;
	Kappa[] kappaEnemies;
	Urchin[] bossEnemies;
	Urchin[] arcEnemies;
	public short nUrchinPerlev;
	public short nUrchinPerStep;
	private short nKappaPerStep;
	private short nKappaPerLev;
	private short nArcMonterPerLev;
	private short nArcMonterPerStep;
	private short nBossPerStep;
	private short nBossPerLev;
	short delayBullet = 10;
	short life = 1;
	final short framFloat = 20;
	short nOldUrchin = 0;
	public final static short FRAM_WIDTH = 50;
	final static short W_URCHIN = 141;
	final static short H_URCHIN = 93;
	final static short W_KAPPA = 124;
	final static short H_KAPPA = 124;
	final static short W_ARC = 123;
	final static short H_ARC = 140;
	final static short W_BOSS = 163;
	final static short H_BOSS = 163;
	final static short W_BULLET = 12;
	final static short H_BULLET = 8;
	Weapon[] items;
	Random rd = new Random();
	private int xStep;
	private Image[] imgArc;
	short cheat;

	public void init() {
		// khoi tao dau tien
		CGlobal.SOU_BG.stop();
		level = 1;
		score = 0;
		initLv(level);
		initObj();
		loadImg();
		initItem();
		// khoi tao theo tung level

	}

	/** Khoi tao theo tung level */
	public final void initLv(int levelInit) {
		if (levelInit > CGlobal.MAX_LV || levelInit <= 0) {
			endGame(levelInit > 0);
			return;
		}
		level = levelInit;
		xStep = 0;
		nUrchinPerlev = (short) (50 + (level - 1) * 10);
		nKappaPerLev = (short) (10 + (level - 1) * 5);
		nArcMonterPerLev = (short) (level + 1);
		nBossPerLev = (short) level;
		switch (level) {
		case 1:
			player = new Player(108, 442);
			player.health = 200;
			row = 15;
			column = 72;
			break;
		case 2:
			player.health = 200;
			player.x = 158;
			player.y = 700;
			row = 20;
			column = 50;
			initItem();
			break;
		case 3:
			for (int i = 0; i < player.weapons.length; i++) {
				if (i != 0) {
					player.weapons[i].size = 0;
				}
			}
			player.health = 200;
			player.x = 50;
			player.y = 700;
			row = 25;
			column = 60;
			initItem();
			break;
		case 4:
			player.health = 200;
			player.x = 70;
			player.y = 760;
			row = 25;
			column = 120;
			initItem();
			break;
		case 5:
			player.health = 200;
			player.x = 100;
			player.y = 450;
			row = 18;
			column = 18;
			initItem();
			break;
		default:
			break;
		}
		arrMap = new int[row][column];
		try {
			loadMap();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	public void initObj() {
		imgUrchin = new Image[5];
		imgKappa = new Image[3];
		imgBoss = new Image[5];
		imgArc = new Image[5];
		weapons = new Weapon[4];
		bullets = new Bullet[10];
		// array enemy
		urchinEnemies = new Urchin[10];
		kappaEnemies = new Kappa[10];
		arcEnemies = new Urchin[5];
		bossEnemies = new Urchin[5];
		//
		items = new Weapon[10];
		for (int i = 0; i < 10; i++) {
			if (i < 4) {
				player.weapons[i] = new Weapon();
				player.weapons[i].id = (short) i;
				if (i == 0) { // sung luc
					player.weapons[i].damge = 5;
				}
				if (i == 1) {
					player.weapons[i].damge = 7; // b32
				}
				if (i == 2) { // shot gun
					player.weapons[i].damge = 20;
				}
				if (i == 3) { // ak 46
					player.weapons[i].damge = 15;
				}
			}
			if (i < 10) {
				bullets[i] = new Bullet();
			}
			if (i < 4) {
				arcEnemies[i] = new Urchin();
				bossEnemies[i] = new Urchin();
			}
			urchinEnemies[i] = new Urchin();
			kappaEnemies[i] = new Kappa();
		}

	}

	public void tick() {
		actionKey();
		computeDistance();
		upDate();
	}

	public void upDate() {
		// check collision
		collForPlayer();
		collForEnemy();
		collForBullet();
		player.mWeapon();
		player.update();
		if (player.health <= 0) {
			endGame(false);
		}
		//
		//
		initEnemy();
		for (int i = 0; i < 10; i++) {
			if (urchinEnemies[i] != null && urchinEnemies[i].isActive) {
				{
					urchinEnemies[i].findEnemy(player.x, player.y);
					urchinEnemies[i].update();
				}

			}
			if (kappaEnemies[i] != null && kappaEnemies[i].isActive) {
				{
					kappaEnemies[i].findEnemy(player.x, player.y);
					kappaEnemies[i].update();
				}
			}
			if (i < 4) {
				if (arcEnemies[i] != null && arcEnemies[i].isActive) {
					{
						arcEnemies[i].findEnemy(player.x, player.y);
						arcEnemies[i].update();
						arcEnemies[i].update();
					}
				}
				if (bossEnemies[i] != null && bossEnemies[i].isActive) {
					{
						bossEnemies[i].findEnemy(player.x, player.y);
						bossEnemies[i].update();
					}

				}
			}
		}
	}

	private void collForEnemy() {
		for (int i = 0; i < 10; i++) {
			if (urchinEnemies[i] != null && urchinEnemies[i].isActive) {
				short _x = urchinEnemies[i].x;
				short _y = urchinEnemies[i].y;
				short _vy = urchinEnemies[i].vy;
				// fall
				if (row * FRAM_WIDTH - _y < H_URCHIN + 10) {
					urchinEnemies[i].trungdan(1000);
				}
				// check collision bottom
				if (isColTop(_x, _y, W_URCHIN, H_URCHIN)) {
					if (urchinEnemies[i].isFall || urchinEnemies[i].isJump) {
						urchinEnemies[i].fall(false);
					}
				} else {
					if (!urchinEnemies[i].isJump) {
						urchinEnemies[i].fall(true);
					}
				}
				// check collision top
				if (_y + _vy <= 10) {
					urchinEnemies[i].fall(true);
				}
				if (isColTop(_x, _y - 5, W_URCHIN, 0) || _y + _vy <= 10) {
					if (urchinEnemies[i].isJump) {
						urchinEnemies[i].fall(true);
					}
				}
				// check collision right
				if (isColLef(_x, _y, W_URCHIN, H_URCHIN)) {
					urchinEnemies[i].collMap = 3;
				}
				// check collision left
				if (isColLef(_x, _y, -10, H_URCHIN)) {
					urchinEnemies[i].vx = 0;
					urchinEnemies[i].collMap = 2;
				}
				// check collision with player
				if (player.collWithEnemy(_x, _y, W_URCHIN, H_URCHIN)) {
					player.trungdan(urchinEnemies[i].damge);
					urchinEnemies[i].damge = 0;
				}
			}
			// Kappa -- enemy
			if (kappaEnemies[i] != null && kappaEnemies[i].isActive) {
				if (player.collWithEnemy(kappaEnemies[i].x, kappaEnemies[i].y,
						W_KAPPA, H_KAPPA)) {
					player.trungdan(kappaEnemies[i].damge);
					kappaEnemies[i].damge = 0;
				}
			}
		}
		// arc -- top map
		for (int i = 0; i < 5; i++) {
			if (arcEnemies[i] != null && arcEnemies[i].isActive) {
				// fall
				if (row * FRAM_WIDTH - arcEnemies[i].y < H_ARC + 10) {
					arcEnemies[i].trungdan(1000);
				}
				if (isColTop(arcEnemies[i].x, arcEnemies[i].y, W_ARC, H_ARC)) {
					if (arcEnemies[i].isFall || arcEnemies[i].isJump) {
						arcEnemies[i].fall(false);
					}
				} else {
					if (!arcEnemies[i].isJump) {
						arcEnemies[i].fall(true);
					}
				}
				if (arcEnemies[i].y + urchinEnemies[i].vy <= 10) {
					arcEnemies[i].fall(true);
				}
				// arc - enemy
				if (player.collWithEnemy(arcEnemies[i].x, arcEnemies[i].y,
						W_ARC, H_ARC)) {
					player.trungdan(arcEnemies[i].damge);
					arcEnemies[i].damge = 0;
				}
				// arc-left map
				if (isColLef(arcEnemies[i].x, arcEnemies[i].y, W_ARC, H_ARC)) {
					arcEnemies[i].collMap = 3;
				}
				// arc-right map
				if (isColLef(arcEnemies[i].x, arcEnemies[i].y, -10, H_ARC)) {
					arcEnemies[i].vx = 0;
					arcEnemies[i].collMap = 2;
				}
			}
			// boss -- top map
			if (bossEnemies[i] != null && bossEnemies[i].isActive) {
				// fall
				if (row * FRAM_WIDTH - bossEnemies[i].y < H_BOSS + 10) {
					bossEnemies[i].trungdan(1000);
				}
				if (isColTop(bossEnemies[i].x, bossEnemies[i].y, W_BOSS, H_BOSS)) {
					if (bossEnemies[i].isFall || bossEnemies[i].isJump) {
						bossEnemies[i].fall(false);
					}
				} else {
					if (!bossEnemies[i].isJump) {
						bossEnemies[i].fall(true);
					}
				}
				if (bossEnemies[i].y + bossEnemies[i].vy <= 10) {
					bossEnemies[i].fall(true);
				}
				// boss - PLAYER
				if (player.collWithEnemy(bossEnemies[i].x, bossEnemies[i].y,
						W_BOSS, H_BOSS)) {
					player.trungdan(bossEnemies[i].damge);
					bossEnemies[i].damge = 0;
				}
				// boss-left map
				if (isColLef(bossEnemies[i].x, bossEnemies[i].y, W_BOSS, H_BOSS)) {
					bossEnemies[i].collMap = 3;
				}
				// boss-right map
				if (isColLef(bossEnemies[i].x, bossEnemies[i].y, -10, H_BOSS)) {
					bossEnemies[i].vx = 0;
					bossEnemies[i].collMap = 2;
				}
				// end boss
			}
		}

	}

	public boolean isColTop(int x, int y, int wx, int hy) {
		int _temp;
		for (int i = 0; i < 6; i++) {
			_temp = arrMap[(y + hy) / FRAM_WIDTH][(x + i * (wx / 6))
					/ FRAM_WIDTH];
			if (_temp > 0) {
				return true;
			}
		}
		return false;
	}

	public boolean isColLef(int x, int y, int wx, int hy) {
		for (int i = 0; i < 4; i++) {
			int _temp = arrMap[(y + i * (hy / 4)) / FRAM_WIDTH][(x + wx)
					/ FRAM_WIDTH];
			if (_temp > 0) {
				return true;
			}
		}
		return false;
	}

	private void collForPlayer() {
		short _x = player.x;
		short _y = player.y;
		short _w = (short) player.getWidth();
		short _h = (short) player.getHeight();
		short _vx = player.vx;
		short _vy = player.vy;
		if (row * FRAM_WIDTH - _y <= player.getHeight() + 10) {
			endGame(false);
			return;
		}
		if (isColTop(_x, _y, _w, _h)) {
			if (player.isJump) {
				player.vy = 0;
				player.isJump = false;
				player.isDJump = false;
				player.isFall = false;
			}
		} else {
			if (!player.isJump || !player.isDJump) {
				player.isJump = true;
				player.y += 5;
			}
		}
		// collision with map top
		if (isColTop(_x, _y - 5, _w, 0) || _y + _vy <= 10) {
			if (player.isJump) {
				player.vy = 0;
				player.vx = 0;
				player.y += 10;
			}
		}
		// collision with map left
		if (isColLef(_x, _y, -10, _h)) {
			player.vx = 0;
			player.isCollision = 3;
		}
		// collision with map right
		if (isColLef(_x, _y, (_w + _vx), _h)) {
			player.vx = 0;
		}
		if (_x + _vx < 10) {
			player.vx = 0;
		}
		// fall

		// collision with items
		for (int i = 0; i < 10; i++) {
			if (items[i] != null && items[i].isActive) {
				if (player.collWithEnemy(items[i].x, items[i].y, items[i]
						.getWidth(), items[i].getHeight())) {
					if (items[i].type == 0) {
						player.health += items[i].size;
						player.health = player.health - 200 > 0 ? 200
								: player.health;
					} else {
						player.pickItem(items[i]);
					}
					items[i].isActive = false;
				}
			}
		}
	}

	public void collForBullet() {
		for (int i = 0; i < 10; i++) {
			if (!bullets[i].isActive) {
				break;
			}
			short damge = player.weapon.damge;
			// collision map
			if (bullets[i].x - 10 <= 10
					|| bullets[i].x + FRAM_WIDTH > column * FRAM_WIDTH
					|| isColLef(bullets[i].x, bullets[i].y, W_BULLET, H_BULLET)) {
				bullets[i].explore();
			}
			// end collision map
			for (int j = 0; j < 10; j++) {
				// urchin
				if (urchinEnemies[j] != null && urchinEnemies[j].isActive) {
					if (bullets[i].isCollWithEnemy(urchinEnemies[j].x,
							urchinEnemies[j].y, W_URCHIN, H_URCHIN)) {
						if (urchinEnemies[j].trungdan(damge)) {
							score += 50;
							nUrchinPerlev--;
						}
						bullets[i].explore();
						break;
					}
				}
				// kappa
				if (kappaEnemies[j] != null && kappaEnemies[j].isActive) {
					if (bullets[i].isCollWithEnemy(kappaEnemies[j].x,
							kappaEnemies[j].y, W_KAPPA, H_KAPPA)) {
						if (kappaEnemies[j].trungdan(damge)) {
							score += 100;
							nKappaPerLev--;
						}
						bullets[i].explore();
						break;
					}

				}
				// arc
				if (j < 4 && arcEnemies[j] != null && arcEnemies[j].isActive) {
					if (bullets[i].isCollWithEnemy(arcEnemies[j].x,
							arcEnemies[j].y, W_ARC, H_ARC)) {
						if (arcEnemies[j].trungdan(damge)) {
							score += 200;
							nArcMonterPerLev--;
						}
						bullets[i].explore();
						break;
					}
				}
				// boss
				if (j < 4 && bossEnemies[j] != null && bossEnemies[j].isActive) {
					if (bullets[i].isCollWithEnemy(bossEnemies[j].x,
							bossEnemies[j].y, W_BOSS, H_BOSS)) {
						if (bossEnemies[j].trungdan(damge)) {
							score += 500;
							nBossPerLev--;
						}
						bullets[i].explore();
						break;
					}
				}
			}
		}
	}

	public void initItem() {
		// create weapon
		switch (level) {
		case 1:
			items[0] = new Weapon();
			items[0].createItem(1, 1, 1050, 100, 200, true);
			items[0].image = player.weapons[1].image;
			items[0].imageS = player.weapons[1].imageS;

			items[1] = new Weapon();
			items[1].createItem(2, 1, 90, 350, 30, true);
			items[1].image = player.weapons[2].image;
			items[1].imageS = player.weapons[2].imageS;

			items[2] = new Weapon();
			items[2].createItem(3, 1, 1795, 100, 150, true);
			items[2].image = player.weapons[3].image;
			items[2].imageS = player.weapons[3].imageS;

			items[3] = new Weapon();
			items[3].createItem(0, 0, 1208, 473, 50, true);
			items[3].image = imgHealth;
			items[3].imageS = imgHealth;
			imgHealth = null;
			break;
		case 2:
			items[0].createItem(1, 1, 540, 740, 200, true);

			items[2].createItem(3, 1, 1467, 400, 150, true);
			break;
		case 3:
			items[0].createItem(1, 1, 1100, 400, 200, true);
			break;
		case 4:
			items[1].createItem(2, 1, 500, 900, 30, true);
			items[3].createItem(0, 0, 1150, 600, 50, true);
			items[2].createItem(3, 1, 1150, 218, 150, true);
			break;
		case 5:
			items[0].createItem(1, 1, 193, 600, 400, true);
			items[1].createItem(2, 1, 307, 600, 60, true);
			items[2].createItem(3, 1, 500, 600, 150, true);
			items[3].createItem(0, 0, 750, 600, 1999, true);
			break;
		default:
			break;
		}
	}

	public void shoot() {
		player.shoot();
		int _x = player.x;
		int _y = player.y + 5;
		int _idWeapon = player.weapon.id;
		short _ntemp = 1;
		short _speed = 0;
		if (player.direction) {
			if (_idWeapon == 0) { // sung luc
				_x += 30;
				_y += 50;
			} else if (_idWeapon == 1) { // b32
				_x += 70;
				_y += 45;
				_ntemp = 2;
				_speed = 25;
			} else if (_idWeapon == 2) { // shot gun
				_x += 85;
				_y += 47;
			} else if (_idWeapon == 3) { // ak 47
				_x += 90;
				_y += 48;
				_ntemp = 3;
				_speed = 25;
			}
		} else {
			if (_idWeapon == 0) {
				_x += 40;
				_y += 50;
			} else if (_idWeapon == 1) {
				_x -= 5;
				_y += 45;
				_ntemp = 3;
				_speed = -25;
			} else if (_idWeapon == 2) {
				_x -= 10;
				_y += 47;
			} else if (_idWeapon == 3) {
				_x -= 20;
				_y += 48;
				_ntemp = 5;
				_speed = -25;
			}
		}
		for (int j = 0; j < _ntemp; j++) {
			for (int i = 0; i < 10; i++) {
				if (!bullets[i].isActive) {
					bullets[i].direction = player.direction;
					bullets[i].image = imgBullet;
					bullets[i].shoot(_x + (j * _speed), _y);
					bullets[i].idWeapon = player.weapon.id;
					if (player.weapon.id != 0)
						player.weapon.size -= 1;
					break;
				}
			}
		}
	}

	void resetEnemy() {
		for (int i = 0; i < 10; i++) {
			urchinEnemies[i] = new Urchin();
			kappaEnemies[i] = new Kappa();
			if (i < 4) {
				arcEnemies[i] = new Urchin();
				bossEnemies[i] = new Urchin();
				// reset item
				items[i].x = -100;
				items[i].y = -100;
			}
		}
	}

	void xEnemy(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {
		for (int i = 0; i < 10; i++) {
			if (!urchinEnemies[i].isActive && nUrchinPerStep >= 1) {
				urchinEnemies[i].active(1, x1 + (rd.nextInt(4) * 50), y1, 20,
						1, imgUrchin);
				nUrchinPerStep--;
			}
			if (!kappaEnemies[i].isActive && nKappaPerStep >= 1) {
				kappaEnemies[i].active(x2 + (rd.nextInt(4) * 50), y2, 30, 1,
						imgKappa);
				nKappaPerStep--;
			}
			if (i < 4 && !arcEnemies[i].isActive && nArcMonterPerStep >= 1) {
				arcEnemies[i].active(2, x3 + (rd.nextInt(4) * 50), y3, 50, 1,
						imgArc);
				nArcMonterPerStep--;
			}
			if (i < 4 && !bossEnemies[i].isActive && nBossPerStep >= 1) {
				bossEnemies[i].active(3, x4 + (rd.nextInt(4) * 50), y4,
						100 + (level - 1) * 30, 1, imgBoss);
				nBossPerStep--;
			}
		}
	}

	public void initEnemy() {
		// /System.out.println("step_" + xStep);
		// System.out.println("boss per lv" + nBossPerLev);
		// System.out.println("boss per step" + nBossPerStep);
		// System.out.println("urchin" + nUrchinPerlev);
		// System.out.println("kappa" + nKappaPerLev);
		// System.out.println("arc" + nArcMonterPerLev);
		// System.out.println("boss" + nBossPerLev);
		// System.out.println("xstep" + xStep);
		switch (level) {
		case 1:// level 1
			if (nBossPerLev <= 0) {
				System.out.println("Win");
				score += 1000;
				xStep = 0;
				nextLv();
				break;
			}
			if (player.x > 300 && xStep == 0) {
				xStep += 1;
				nUrchinPerStep = 10;
				nKappaPerStep = 3;

			} else if (player.x > 1200 && xStep == 1 && nUrchinPerStep == 0) {
				xStep += 1;
				nUrchinPerStep = 15;
				nKappaPerStep = 3;
				nArcMonterPerStep = 1;

			} else if (player.x > 2900 && xStep == 2 && nUrchinPerStep == 0) {
				xStep += 1;
				nUrchinPerStep = 25;
				nKappaPerStep = 4;
				nArcMonterPerStep = 1;
				nBossPerStep = 1;
			}
			switch (xStep) {
			case 1:
				xEnemy(700, 477, 700, 477, 0, 0, 0, 0);
				break;
			case 2:
				xEnemy(1800, 236, 1800, 477, 1800, 200, 1800, 236);
				break;
			case 3:
				xEnemy(3100, 100, 3100, 477, 3100, 100, 3250, 100);
				break;
			default:
				break;
			}
			break;// end level 1
		case 2: // level 2
			if (nBossPerLev <= 0) {
				System.out.println("Win");
				score += 1000;
				xStep = 0;
				nextLv();
				break;
			}
			if (player.x > 300 && xStep == 0) {
				xStep += 1;
				nUrchinPerStep = 15;
				nKappaPerStep = 5;
				nArcMonterPerStep = 1;
			} else if (player.x > 833 && xStep == 1) {
				xStep += 1;
				nUrchinPerStep = 15;
				nKappaPerStep = 5;
				nArcMonterPerStep = 2;
				nBossPerStep = 1;
			} else if (player.x > 1157 && xStep == 2) {
				xStep += 1;
				nUrchinPerStep = 30;
				nKappaPerStep = 9;
				nArcMonterPerStep = 3;
				nBossPerStep = 2;
			}
			switch (xStep) {
			case 1:
				xEnemy(526, 730, 600, 300, 700, 524, 0, 0);
				break;
			case 2:
				xEnemy(1200, 400, 1250, 300, 1200, 524, 1280, 500);
				break;
			case 3:
				xEnemy(1900, 400, 1950, 300, 2000, 524, 2050, 500);
				break;
			default:
				break;
			}
			break;// end level 2
		case 3: // level 3
			if (player.x > 2900) {
				System.out.println("Win");
				score += 1000;
				xStep = 0;
				nextLv();
				break;
			}
			if (player.x > 150 && xStep == 0) {
				xStep += 1;
				nKappaPerStep = 2;
			} else if (player.x > 924 && xStep == 1) {
				xStep += 1;
				nKappaPerStep = 3;
				// nArcMonterPerStep = 3;
				nBossPerStep = 1;
			} else if (player.x > 1837 && xStep == 2) {
				xStep += 1;
				nKappaPerStep = 5;
			} else if (player.x > 2361 && xStep == 3) {
				xStep += 1;
				nKappaPerStep = 7;
			}
			switch (xStep) {
			case 1:
				xEnemy(0, 0, 612, 581, 0, 0, 0, 0);
				break;
			case 2:
				xEnemy(0, 0, 1433, 936, 0, 0, 1450, 700);
				break;
			case 3:
				xEnemy(0, 0, 2168, 400, 0, 0, 0, 0);
				break;
			case 4:
				xEnemy(0, 0, 2600, 500, 0, 0, 0, 0);
				break;
			default:
				break;
			}
			break;// end level 3
		case 4: // lv 4
			if (player.x > 3155) {
				System.out.println("Win");
				score += 1000;
				xStep = 0;
				nextLv();
				break;
			}
			if (player.x > 475 && xStep == 0) {
				xStep += 1;
				nUrchinPerStep = 10;
				nKappaPerStep = 2;
				nArcMonterPerStep = 1;
			} else if (player.x > 924 && xStep == 1) {
				xStep += 1;
				nKappaPerStep = 3;
				nArcMonterPerStep = 3;
				nUrchinPerStep = 5;
			} else if (player.x > 1387 && xStep == 2) {
				xStep += 1;
				nKappaPerStep = 5;
				nArcMonterPerStep = 5;
				nUrchinPerStep = 15;
				nBossPerStep = 1;
				if (player.x > 1700 && player.y < 300 && xStep == 5) {
					xStep += 1;
					nKappaPerStep = 7;
				}
			} else if (player.x > 1800 && xStep == 3) {
				xStep += 1;
				nKappaPerStep = 3;
				nArcMonterPerStep = 4;
				nUrchinPerStep = 25;
				nBossPerStep = 1;
			} else if (player.x > 2700 && xStep == 4) {
				xStep += 1;
				nKappaPerStep = 5;
				nArcMonterPerStep = 5;
				nUrchinPerStep = 35;
				nBossPerStep = 2;
			}

			switch (xStep) {
			case 1:
				xEnemy(700, 1000, 700, 500, 700, 900, 0, 0);
				break;
			case 2:
				xEnemy(0, 0, 1000, 500, 0, 0, 0, 0);
				break;
			case 3:
				xEnemy(1650, 950, 1600, 1000, 1690, 1000, 1700, 1000);
				break;
			case 4:
				xEnemy(2300, 950, 2600, 500, 2300, 1000, 2450, 1000);
				break;
			case 5:
				xEnemy(0, 0, 2600, 500, 0, 0, 0, 0);
				break;
			case 6:
				xEnemy(0, 0, 2200, 350, 0, 0, 0, 0);
				break;

			default:
				break;
			}
			break; // end of lv 4
		case 5:
			boolean _flag = false;
			if (nBossPerLev <= 0 && xStep == 4) {
				System.out.println("Win");
				score += 1000;
				xStep = 0;
				endGame(true);
				break;
			}
			for (int i = 0; i < 3; i++) {
				if (items[i].isActive == true) {
					_flag = false;
					break;
				} else {
					_flag = true;
				}
			}
			if (_flag && xStep == 0) {
				xStep += 1;
				nUrchinPerStep = 15;
				nKappaPerStep = 3;
			} else if (nUrchinPerlev <= 75 && nKappaPerLev <= 27 && xStep == 1) {
				xStep += 1;
				nUrchinPerStep = 20;
				nKappaPerStep = 6;
				nArcMonterPerStep = 2;
			} else if (nUrchinPerlev <= 55 && nKappaPerStep <= 22 && xStep == 2) {
				xStep += 1;
				nUrchinPerStep = 25;
				nKappaPerStep = 9;
				nArcMonterPerStep = 3;
				nBossPerStep = 1;
				initItem();
			} else if (_flag && xStep == 3) {
				xStep += 1;
				nArcMonterPerStep = 1;
				nBossPerStep = 4;

			}
			switch (xStep) {
			case 1:
				xEnemy(400, 600, 410, 400, 430, 400, 0, 0);
				break;
			case 2:
				xEnemy(400, 600, 410, 400, 430, 400, 0, 0);
				break;
			case 3:
				xEnemy(400, 600, 410, 400, 430, 400, 400, 400);
				break;
			case 4:
				xEnemy(400, 600, 410, 400, 430, 400, 400, 400);
				break;
			case 5:
				xEnemy(400, 600, 410, 400, 430, 400, 400, 400);
				break;
			default:
				break;
			}
			break;
		default:
			break;
		}
	}

	/** Su kien nhan phim */
	private final void actionKey() {
		/* function */
		if (press[keyUp]) {
			System.out.println("[scroll up]");
			player.move(3);
			if (cheat == 3) {
				cheat = 4;
			} else {
				cheat = 0;
			}
			// resetKey(keyUp);
		} else if (press[keyDown]) {
			System.out.println("[scroll down]");
			cheat += 1;
			if (cheat > 3) {
				cheat = 0;
			}
			// resetKey(keyDown);
		} else if (press[keyLeft]) {
			System.out.println("[scroll left]");
			player.move(1);
			cheat = 0;
			// resetKey(keyLeft);
		} else if (press[keyRight]) {
			System.out.println("[scroll right]");
			player.move(2);
			cheat = 0;
			// resetKey(keyRight);
		} else if (press[keyOk]) {
			System.out.println("[ok] reset all key");
			shoot();
			if (cheat == 4) {
				cheat = 5;
			} else {
				cheat = 0;
			}
			if (cheat == 5) {
				cheat();
			}
			resetKeys();
		}
		/* pause */
		else if (press[keyMenu]) {
			newSubWin(new InPause());
			return;
		}
		/* debug */
		else if (CGlobal.testMode) {
			if (press[key9]) {
				nextLv();
				return;
			} else if (press[key0]) {
				endGame(false);
				return;
			}
		}
	}

	void cheat() {
		player.health = 9999;
		player.weapon.size = 0;
		items[2].size = 9999;
		player.pickItem(items[2]);

	}

	public void draw(Graphics g) {
		g.setColor(0x0);
		g.fillRect(0, 0, WIDTH, HEIGH);
		g.drawImage(imgbg, inX, inY, Graphics.LEFT | Graphics.TOP);
		player.draw(g);
		// bullet

		for (int i = 0; i < 10; i++) {

			if (urchinEnemies[i] != null && urchinEnemies[i].isActive
					&& urchinEnemies[i].status == 1) {
				// System.out.println("X__" + urchinEnemies[i].x);
				// System.out.println("Y__" + urchinEnemies[i].y);
				urchinEnemies[i].draw(g);
			}
			if (kappaEnemies[i] != null && kappaEnemies[i].isActive
					&& kappaEnemies[i].status == 1) {
				kappaEnemies[i].draw(g);
			}

			if (i < 5 && arcEnemies[i] != null && arcEnemies[i].isActive
					&& (arcEnemies[i].status == 1)) {
				arcEnemies[i].draw(g);
			}
			// boss
			if (i < 5 && bossEnemies[i] != null && bossEnemies[i].isActive
					&& (bossEnemies[i].status == 1)) {
				bossEnemies[i].draw(g);
			}

			if (items[i] != null && items[i].isActive) {
				items[i].drawItem(g);
			}
			if (bullets[i].isActive) {
				bullets[i].draw(g);
			}
		}
		// map
		for (int i = 0; i < row; i++) {
			for (int j = 0; j < column; j++) {
				if (arrMap[i][j] > 0 && arrMap[i][j] <= 19)
					g.drawRegion(imgTile, 0, (arrMap[i][j] - 1) * FRAM_WIDTH,
							FRAM_WIDTH, FRAM_WIDTH, Sprite.TRANS_NONE,
							(j * FRAM_WIDTH) - distance_x, (i * FRAM_WIDTH)
									- distance_y, Graphics.LEFT | Graphics.TOP);
			}
		}
		// urchins enemy
		g.drawImage(imgScore, inX, 500 + inY, Graphics.LEFT | Graphics.BOTTOM);
		// Weapon
		if (player.weapon.imageS != null) {
			g.drawImage(player.weapon.imageS, 355, 489, Graphics.LEFT
					| Graphics.TOP);
			CGlobal.drawNumber(player.weapon.size, 355 + player.weapon.imageS
					.getWidth(), 489, g);
		}
		// Life
		// g.drawImage(imgLife, 114, 489, Graphics.LEFT | Graphics.TOP);
		// CGlobal.drawNumber(life, 144, 489, g);
		// heath
		g.drawImage(imgLife, 134, 489, Graphics.LEFT | Graphics.TOP);
		CGlobal
				.drawNumber(player.health, 134 + imgLife.getWidth() + 10, 489,
						g);
		// info
		CGlobal.drawNumber(score, 25, 20, g);
		CGlobal.drawNumber(level, 85, 489, g);
	}

	public void destroy() {
		imgbg = null;
		if (CGlobal.IS_PLAY_SOUND)
			CGlobal.SOU_BG.play();
	}

	/** Qua man */
	private final void nextLv() {
		if (level + 1 > CGlobal.MAX_LV) {
			endGame(true);
		} else {
			resetEnemy();
			newSubWin(new InPassLv());
		}
	}

	/** Xu ly ket thuc game */
	private final void endGame(boolean isWin) {
		newSubWin(new InOver());
		InOver over = (InOver) getWin(InOver.class);
		over.setContent(isWin, score);
	}

	private final void loadImg() {
		try {
			imgbg = Image.createImage("/bg.jpg");
			// player
			player.images[0] = Image.createImage("/zin/1.png");
			player.images[1] = Image.createImage("/zin/2.png");
			player.images[2] = Image.createImage("/zin/3.png");
			player.images[3] = Image.createImage("/zin/4.png");
			player.images[4] = Image.createImage("/zin/5.png");
			player.images[5] = Image.createImage("/zin/5.1.png");
			player.images[6] = Image.createImage("/zin/6.png");
			player.images[7] = Image.createImage("/zin/7.png");
			// Weapon
			for (int i = 0; i < 4; i++) {
				player.weapons[i].image = Image.createImage("/sung/" + (i + 1)
						+ ".png");
				player.weapons[i].imageS = Image.createImage("/sung/" + (i + 1)
						+ ".1.png");
			}
			// Bullet
			imgBullet = Image.createImage("/danbay.png");
			// Urchin
			imgUrchin[0] = Image.createImage("/enemy2/1.png");
			imgUrchin[1] = Image.createImage("/enemy2/2.png");
			imgUrchin[2] = Image.createImage("/enemy2/3.png");
			imgUrchin[3] = Image.createImage("/enemy2/4.png");
			imgUrchin[4] = Image.createImage("/enemy2/5.png");
			imgKappa[0] = Image.createImage("/enemy3/1.png");
			imgKappa[1] = Image.createImage("/enemy3/2.png");
			imgKappa[2] = Image.createImage("/enemy3/3.png");
			imgArc[0] = Image.createImage("/enemy1/1.png");
			imgArc[1] = Image.createImage("/enemy1/2.png");
			imgArc[2] = Image.createImage("/enemy1/3.png");
			imgArc[3] = Image.createImage("/enemy1/4.png");
			imgArc[4] = Image.createImage("/enemy1/5.png");
			imgBoss[0] = Image.createImage("/boss/1.png");
			imgBoss[1] = Image.createImage("/boss/2.png");
			imgBoss[2] = Image.createImage("/boss/3.png");
			imgBoss[3] = Image.createImage("/boss/4.png");
			imgBoss[4] = Image.createImage("/boss/5.png");

			// Map
			imgScore = Image.createImage("/img/bar.png");
			imgTile = Image.createImage("/tile.png");
			// player.weapon.setImage(Image.createImage("/Player/1.png"));
			// Life
			imgLife = Image.createImage("/img/mang.png");
			imgHealth = Image.createImage("/img/hp.png");
		} catch (IOException e) {
			if (CGlobal.testMode)
				e.printStackTrace();
		}
	}

	private void computeDistance() {
		distance_x = player.x - 300;
		distance_y = player.y - 250;
		if (player.x - 300 < 0)
			distance_x = 0;
		if (player.y - 250 < 0)
			distance_y = 0;
		if (player.x > (column * FRAM_WIDTH - 600))
			distance_x = column * FRAM_WIDTH - 600;
		if (player.y - 194 > (row * FRAM_WIDTH - 500 - inY))
			distance_y = row * FRAM_WIDTH - 500 - inY;
	}

	public void loadMap() throws IOException {
		// System.out.println("chay dau");
		InputStream is = "".getClass().getResourceAsStream(
				"/map/map" + level + ".dat");
		// InputStream is = "".getClass().getResourceAsStream("/map/map11.dat");
		try {
			ByteArrayOutputStream bStrm = new ByteArrayOutputStream();
			int ch;
			while ((ch = is.read()) != -1) {
				bStrm.write(ch);
			}
			byte imageData[] = bStrm.toByteArray();
			int k = 0;
			for (int i = 0; i < row; i++) {
				for (int j = 0; j < column; j++) {
					if (imageData[k] > 0 && imageData[k] <= 19)
						arrMap[i][j] = imageData[k];
					else
						arrMap[i][j] = 0;
					k++;
				}
			}
			bStrm.close();
		} finally {
			if (is != null)
				is.close();
		}
	}
}
